package com.base.cn.platform.os.service.user.user;

import com.base.cn.platform.os.common.j2cache.CustomCacheChannel;
import com.base.cn.platform.os.common.j2cache.J2CacheRegion;
import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.BaseEntity;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.service.CommonSetSubjectDataService;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.DateUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.Security.PurseSecurityUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.common.utils.user.UserExpandFrom;
import com.base.cn.platform.os.dao.user.signin.CusUserSignInDao;
import com.base.cn.platform.os.dao.user.user.CusUserDao;
import com.base.cn.platform.os.entity.course.cou.record.CoursePlayRecord;
import com.base.cn.platform.os.entity.course.cou.record.CoursePlayRecordCondition;
import com.base.cn.platform.os.entity.manage.subject.SysSubject;
import com.base.cn.platform.os.entity.statistics.users.UserCountEntity;
import com.base.cn.platform.os.entity.statistics.users.UserRegFromEntity;
import com.base.cn.platform.os.entity.user.address.CusUserAddress;
import com.base.cn.platform.os.entity.user.count.UserRanking;
import com.base.cn.platform.os.entity.user.count.UserRegDayNum;
import com.base.cn.platform.os.entity.user.count.UserRegFromNum;
import com.base.cn.platform.os.entity.user.count.UserRegLayoutNum;
import com.base.cn.platform.os.entity.user.exprule.CusUserExpAccount;
import com.base.cn.platform.os.entity.user.gradeconfig.CusUserGradeConfig;
import com.base.cn.platform.os.entity.user.integral.CusUserIntegral;
import com.base.cn.platform.os.entity.user.member.CusUserMemberBuyRecord;
import com.base.cn.platform.os.entity.user.signin.CusUserSignIn;
import com.base.cn.platform.os.entity.user.user.CusUser;
import com.base.cn.platform.os.entity.user.user.UserCondition;
import com.base.cn.platform.os.service.course.cou.record.CourseLearnFlowService;
import com.base.cn.platform.os.service.course.cou.record.CoursePlayRecordService;
import com.base.cn.platform.os.service.exam.record.ExamRecordService;
import com.base.cn.platform.os.service.manage.order.goods.OrderService;
import com.base.cn.platform.os.service.manage.subject.SysSubjectBiz;
import com.base.cn.platform.os.service.user.account.CusUserAccountBiz;
import com.base.cn.platform.os.service.user.address.CusUserAddressBiz;
import com.base.cn.platform.os.service.user.exprule.CusUserExpAccountBiz;
import com.base.cn.platform.os.service.user.gradeconfig.CusUserGradeConfigBiz;
import com.base.cn.platform.os.service.user.integral.CusUserIntegralBiz;
import com.base.cn.platform.os.service.user.member.CusUserMemberBuyRecordBiz;
import com.base.cn.platform.os.service.user.signin.CusUserSignInBiz;
import com.github.pagehelper.PageInfo;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 用户Biz
 *
 * @author s.li
 * @create 2018-04-10-13:38
 */
@Service
public class CusUserBiz extends BaseBiz<CusUser, CusUserDao> {
    private static final int HMAC_KEY_LEN = 60;
    @Autowired
    private SysSubjectBiz sysSubjectBiz;
    @Autowired
    private CusUserExpAccountBiz cusUserExpAccountBiz;
    @Autowired
    private CusUserGradeConfigBiz cusUserGradeConfigBiz;
    @Autowired
    private CusUserIntegralBiz cusUserIntegralBiz;
    @Autowired
    private CusUserAddressBiz cusUserAddressBiz;
    @Autowired
    private CusUserMemberBuyRecordBiz cusUserMemberBuyRecordBiz;
    @Autowired
    private CusUserDao cusUserDao;
    @Autowired
    private CusUserAccountBiz cusUserAccountBiz;
    @Autowired
    private OrderService orderService;
    @Autowired
    private CommonSetSubjectDataService<CusUser> commonSetSubjectDataService;
    @Autowired
    private CoursePlayRecordService coursePlayRecordService;
    @Autowired
    private CusUserSignInDao cusUserSignInDao;
    @Autowired
    private ExamRecordService examRecordService;
    @Autowired
    private CourseLearnFlowService courseLearnFlowService;
    @Autowired
    private CustomCacheChannel customCacheChannel;

    /**
     * 更改用戶购买状态
     *
     * @param userId 用户Id
     */
    @Async
    public void updateUserBuyCourse(BigDecimal userId) {
        CusUser user = new CusUser();
        user.setBuyCourse(2);
        this.updateByWhereSql(user, " id = " + userId + " and buyCourse = 1");
    }

    /**
     * 获取用户学业信息
     *
     * @param userId 用户ID
     */
    public List<SysSubject> getUserNaturalSubject(BigDecimal userId) {
        List<String> containColumns = new ArrayList<>();
        containColumns.add("id");
        containColumns.add("naturalSubjectIds");
        CusUser user = this.findOne("id=" + userId, containColumns);
        if (ObjectUtils.isNotEmpty(user)) {
            String naturalSubjectIds = user.getNaturalSubjectIds();
            if (StringUtils.isNotEmpty(naturalSubjectIds)) {
                naturalSubjectIds = naturalSubjectIds.replaceAll("#", ",").replaceAll(",,", ",");
                naturalSubjectIds = StringUtils.subHeadTailString(naturalSubjectIds, ",");
                Set<String> set = new HashSet<>();
                Arrays.stream(naturalSubjectIds.split(",")).forEach(str -> {
                    set.add(str);
                });
                String subjectIds = set.stream().distinct().collect(Collectors.joining(","));
                SysSubject subject = new SysSubject();
                subject.setQueryIds(subjectIds);
                List<SysSubject> subjectList = sysSubjectBiz.findLayeredSubjectList(subject);
                return subjectList;
            }
        }
        return null;
    }

    /**
     * 条件查询Sql
     *
     * @param userCondition 查询条件
     */
    public String whereUserSql(UserCondition userCondition) {
        String whereSql = " status=1 ";
        if (ObjectUtils.isNotEmpty(userCondition)) {
            if (StringUtils.isNotEmpty(userCondition.getKeyWord())) {
                whereSql += " and (mobile like concat('%','" + userCondition.getKeyWord().trim() + "','%')" +
                        " or email like concat('%','" + userCondition.getKeyWord().trim() + "','%')" +
                        " or loginAccount like concat('%','" + userCondition.getKeyWord().trim() + "','%')" +
                        " or nickname like concat('%','" + userCondition.getKeyWord().trim() + "','%'))";
            }
            if (StringUtils.isNotEmpty(userCondition.getEmail())) {
                whereSql += " and email like concat('%','" + userCondition.getEmail().trim() + "','%')";
            }
            if (StringUtils.isNotEmpty(userCondition.getMobile())) {
                whereSql += " and mobile like concat('%','" + userCondition.getMobile().trim() + "','%')";
            }
            if (StringUtils.isNotEmpty(userCondition.getLoginAccount())) {
                whereSql += " and loginAccount like concat('%','" + userCondition.getLoginAccount().trim() + "','%')";
            }
            if (StringUtils.isNotEmpty(userCondition.getRegisterFrom())) {
                whereSql += " and registerFrom='" + userCondition.getRegisterFrom() + "'";
            }
            if (ObjectUtils.isNotEmpty(userCondition.getIsavalible())) {
                whereSql += " and isavalible=" + userCondition.getIsavalible();
            }
            if (StringUtils.isNotEmpty(userCondition.getNickname())) {
                whereSql += " and nickname like concat('%','" + userCondition.getNickname() + "','%')";
            }
            if (StringUtils.isNotEmpty(userCondition.getRealName())) {
                whereSql += " and realName like concat('%','" + userCondition.getRealName() + "','%')";
            }
            if (StringUtils.isNotEmpty(userCondition.getSubjectIds())) {
                String where1 = StringUtils.getSubjectSql("naturalSubjectIds", userCondition.getSubjectIds(), userCondition.isQueryNullSubject());
                String where2 = StringUtils.getSubjectSql("subjectIds", userCondition.getSubjectIds(), userCondition.isQueryNullSubject());
                whereSql += " and  ((1=1" + (where1 + ") or (1=1 " + where2 + "))");
            }
            if (StringUtils.isNotEmpty(userCondition.getIds())) {
                whereSql += " and id in(" + userCondition.getIds() + ")";
            }
            if (StringUtils.isNotEmpty(userCondition.getStartDate())) {
                whereSql += " and createTime >= '" + userCondition.getStartDate() + "'";
            }
            if (StringUtils.isNotEmpty(userCondition.getEndDate())) {
                whereSql += " and createTime <= '" + userCondition.getEndDate() + "'";
            }
            if (ObjectUtils.isNotEmpty(userCondition.getOrderBy())) {
                if (userCondition.getOrderBy() == 1) {
                    whereSql += " order by id desc";
                } else if (userCondition.getOrderBy() == 3) {
                    whereSql += " order by studyTotalTime desc";
                }
            }
        }
        return whereSql;
    }

    /**
     * 根据Id搜索学员
     *
     * @param userId
     * @return
     */
    public CusUser queryUserById(BigDecimal userId, boolean subjectData,
                                 boolean userAddresses, boolean expRule,
                                 boolean gradeConfig, boolean integral,
                                 boolean userMember, boolean expAccount) {
        List<CusUser> cusUsers = queryUserByIds(userId + "", subjectData, userAddresses, expRule, gradeConfig, integral, userMember, expAccount);
        if (ObjectUtils.isNotEmpty(cusUsers)) {
            return cusUsers.get(0);
        }
        return null;
    }

    /**
     * 用户学习中心详情
     *
     * @param condition
     * @return
     */
    public CusUser userStudyInfo(UserCondition condition) {
        CusUser cusUser = this.findById(condition.getId());
        setUserStudyData(cusUser, condition);
        if (ObjectUtils.isNotEmpty(cusUser)) {
            return cusUser;

        }
        return null;
    }

    private void setUserStudyData(CusUser cusUser, UserCondition condition) {
        if (ObjectUtils.isNotEmpty(cusUser)) {
            if (condition.isNotStudy()) {
                CoursePlayRecordCondition recordCondition = new CoursePlayRecordCondition();
                recordCondition.setUserId(cusUser.getId());
                List<CoursePlayRecord> coursePlayRecordList = coursePlayRecordService.findCoursePlayRecordList(recordCondition);
                double sum = coursePlayRecordList.stream().filter(c -> DateUtils.format(c.getUpdateTime(), "yyyy-MM-dd").equals(DateUtils.format(new Date(), "yyyy-MM-dd"))).mapToDouble(m -> m.getDurationCatalogNum()).sum();
                long count = coursePlayRecordList.stream().filter(c -> c.getFinish() == 2).count();
                List<String> list = coursePlayRecordList.stream().map(m -> DateUtils.format(m.getUpdateTime(), "yyyy-MM-dd")).distinct().collect(Collectors.toList());
                list.add(DateUtils.format(DateUtils.getDateAfterDays(new Date(),1), "yyyy-MM-dd"));
//                list.add(DateUtils.format(new Date(), "yyyy-MM-dd"));
                list = list.stream().distinct().collect(Collectors.toList());
                Collections.sort(list);
                int i = 0;
                for (int a = list.size() - 1; a > 0; a--) {
                    Date c = DateUtils.parseDate(list.get(a), "yyyy-MM-dd");
                    Date d = DateUtils.parseDate(list.get(a - 1), "yyyy-MM-dd");
                    if (c.getTime() - d.getTime() == 86400000) {
                        ++i;
                    } else {
                        break;
                    }
                }
                cusUser.setTodayCount(divide(sum,60.0,1));
                cusUser.setFinishCount(count);
                cusUser.setContinuityCount(i);
                List<UserRanking> userRankingList= (List<UserRanking>) customCacheChannel.get(J2CacheRegion.ONE_DAY_REGION.getValue(), "userRankingList").getValue();
                if (ObjectUtils.isEmpty(userRankingList)) {
                    userRankingList = cusUserDao.queryUserRanking();
                    customCacheChannel.set(J2CacheRegion.ONE_DAY_REGION.getValue(), "userRankingList", userRankingList);
                }
                if (ObjectUtils.isNotEmpty(userRankingList)) {
                    Map<BigDecimal, Integer>rankingMap = userRankingList.stream().collect(Collectors.toMap(u -> u.getUserId(), u -> u.getRanking()));
                    if (ObjectUtils.isNotEmpty(rankingMap.get(cusUser.getId()))) {
                        cusUser.setRanking(rankingMap.get(cusUser.getId()));
                    }
                    rankingMap=null;
                }
                userRankingList=null;
            }
        }
    }

    /**
     * 根据邮箱搜索学员
     *
     * @param email
     * @return
     */
    public CusUser queryUserByEmail(String email) {

        return this.findOne(" email='" + email.trim() + "'", null);
    }

    /**
     * 根据手机搜索学员
     *
     * @param mobile
     * @return
     */
    public CusUser queryUserByMobile(String mobile) {

        return this.findOne(" mobile='" + mobile.trim() + "'", null);
    }

    /**
     * 根据登录账号搜索学员
     *
     * @param loginAccount
     * @return
     */
    public CusUser queryUserByLoginAccount(String loginAccount) {
        return this.findOne(" loginAccount='" + loginAccount.trim() + "'", null);
    }

    /**
     * 验证用户登录时用
     *
     * @param loginAccount
     * @return
     */
    public CusUser getLongUser(String loginAccount) {
        if (StringUtils.isNotEmpty(loginAccount)) {
            CusUser cusUser = this.findOne(" status=1 and email='" + loginAccount.trim() + "' or mobile='" + loginAccount.trim() + "' or loginAccount='" + loginAccount.trim() + "'", null);
            if (ObjectUtils.isNotEmpty(cusUser)) {
                return cusUser;
            }
        }
        return null;
    }

    /**
     * 后台搜索分页用户列表
     *
     * @param queryUser 搜索条件
     * @param page      分页条件
     * @return PageInfo<User>
     */
    public PageInfo<CusUser> queryUserListPage(Pagination page, UserCondition queryUser) {
        return queryUserListPage(page, queryUser, false, false, false, false, false, false, false);
    }

    /**
     * 后台搜索分页用户列表
     *
     * @param queryUser 搜索条件
     * @param page      分页条件
     * @return PageInfo<User>
     */
    public PageInfo<CusUser> queryUserListPage(Pagination page, UserCondition queryUser, boolean subjectData,
                                               boolean userAddresses, boolean expRule,
                                               boolean gradeConfig, boolean integral,
                                               boolean userMember, boolean expAccount) {
        String whereSql = whereUserSql(queryUser);
        PageInfo<CusUser> cusUserPageInfo = this.findPage(whereSql, page, null);
        //设置扩展数据
        cusUserPageInfo.setList(this.setUserSubjectAndGradeConfigAndEtc(cusUserPageInfo.getList(),
                subjectData, userAddresses, expRule, gradeConfig, integral, userMember, expAccount));
        return cusUserPageInfo;
    }

    /**
     * 根据Ids搜索用户
     *
     * @param userIds
     * @return
     */
    public List<CusUser> queryUserByIds(String userIds, boolean subjectData,
                                        boolean userAddresses, boolean expRule,
                                        boolean gradeConfig, boolean integral,
                                        boolean userMember, boolean expAccount) {
        if (!ObjectUtils.isNotEmpty(userIds)) {
            return new ArrayList<>();
        }
        UserCondition userCondition = new UserCondition();
        userCondition.setIds(userIds);
        return queryUserList(userCondition, null, null, subjectData, userAddresses, expRule, gradeConfig, integral, userMember, expAccount);
    }

    /**
     * 根据Ids搜索用户
     *
     * @param userIds 用户ID
     */
    public Map<BigDecimal, CusUser> queryCusUserMapByUserIds(String userIds, boolean subjectData,
                                                             boolean userAddresses, boolean expRule,
                                                             boolean gradeConfig, boolean integral,
                                                             boolean userMember, boolean expAccount) {
        List<CusUser> cusUserList = this.queryUserByIds(userIds, subjectData, userAddresses, expRule, gradeConfig, integral, userMember, expAccount);
        if (ObjectUtils.isNotEmpty(cusUserList)) {
            return cusUserList.stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
        }
        return null;
    }

    /**
     * 后台搜索用户
     *
     * @param userCondition 搜索条件
     * @return PageInfo<User>
     */
    public List<CusUser> queryUserList(UserCondition userCondition, Integer count, List<String> columns, boolean subjectData,
                                       boolean userAddresses, boolean expRule,
                                       boolean gradeConfig, boolean integral,
                                       boolean userMember, boolean expAccount) {
        String whereSql = this.whereUserSql(userCondition);
        List<CusUser> cusUserList = this.find(whereSql, count, columns);
        cusUserList = setUserSubjectAndGradeConfigAndEtc(cusUserList, subjectData, userAddresses, expRule, gradeConfig, integral, userMember, expAccount);
        return cusUserList;
    }

    /**
     * 创建学员
     *
     * @param user 学员数据对象
     */
    @Transactional
    public CusUser createUser(CusUser user) {
        if (ObjectUtils.isNotEmpty(user)) {
            this.setCusUserData(user);
            if (user.getStatus() == null) {
                user.setStatus(1);
            }
            this.save(user);
            cusUserAccountBiz.createUserAccount(user.getId());
            return user;
        }
        return null;
    }

    /**
     * 批量添加学员
     *
     * @param cusUserList
     */
    @Transactional(rollbackFor = IllegalArgumentException.class)
    @Async
    public void batchCreateUser(List<CusUser> cusUserList) {
        //设置用户数据
        cusUserList.forEach(cusUser -> {
            this.setCusUserData(cusUser);
        });
        this.batchSave(cusUserList);
        //获取用户ID串
        String cusUserIds = cusUserList.stream().map(e -> e.getId().toString()).distinct().collect(Collectors.joining(","));
        //生成用户账户数据
        cusUserAccountBiz.createBatchUserAccount(cusUserIds);
    }


    /**
     * 设置创建用户数据
     *
     * @param cusUser
     */
    private void setCusUserData(CusUser cusUser) {
        //加密密码
        this.generatePassword(cusUser);
        //重组subjectIds
        this.regroupSubjectIds(cusUser);
        //设置后台创建用户自行选择的专业
        cusUser.setNaturalSubjectIds(cusUser.getSubjectIds());
        //默认是普通用户
        if (!ObjectUtils.isNotEmpty(cusUser.getUserType()) || cusUser.getUserType() == 0) {
            cusUser.setUserType(1);
        }
        //验证是否是注册用户
        cusUser.setRegisterType(this.getRegisterType(cusUser.getRegisterFrom()));
        //默认学员昵称
        nickname(cusUser);
        cusUser.setIsavalible(1);
        Date currentTime = new Date();
        //设置最后读取作业的时间
        cusUser.setLastWorkTime(currentTime);
        //设置最后读取消息时间
        cusUser.setLastSystemTime(currentTime);
    }

    /**
     * 重新组合专业ID串
     *
     * @param user
     */
    private void regroupSubjectIds(CusUser user) {
        String subjectIds = user.getSubjectIds();
        if (StringUtils.isNotEmpty(subjectIds)) {
            subjectIds = StringUtils.subHeadTailString(subjectIds, ",");
            String[] ids = subjectIds.split(",");
            if (StringUtils.isNotEmpty(ids) && ids.length > 2) {
                String id = ids[0];
                StringBuffer stringBuffer = new StringBuffer();
                IntStream.range(1, ids.length).forEach(index -> {
                    stringBuffer.append(",").append(id).append(",").append(ids[index]).append(",#");
                });
                subjectIds = StringUtils.subHeadTailString(stringBuffer.toString(), "#");
                user.setSubjectIds(subjectIds);
            }
        }
    }

    /**
     * 重置密码
     *
     * @param userId
     * @return
     */
    public void resetPassword(BigDecimal userId, String rPassword) {
        CusUser user = new CusUser();
        user.setPassword(rPassword);
        this.generatePassword(user);
        this.updateByWhereSql(user, " id=" + userId);
    }

    /**
     * 设计加密密码
     */
    public void generatePassword(CusUser user) {
        String customerKey = StringUtils.getRandomString(HMAC_KEY_LEN);
        String password = PurseSecurityUtils.secrect(user.getPassword(), customerKey);
        user.setPassword(password);
        user.setCustomerkey(customerKey);
    }

    /**
     * 批量禁封登录，批量恢复
     *
     * @param userIds
     * @param isavalible
     * @return
     */
    public void updateUserStatusByUserIds(String userIds, Integer isavalible) {
        if (StringUtils.isNotEmpty(userIds)) {
            UserCondition userContainColumns = new UserCondition();
            userContainColumns.setIds(userIds);
            List<CusUser> userList = this.queryUserList(userContainColumns, null, null,
                    false, false, false,
                    false, false, false, false);
            for (CusUser user : userList) {
                user.setIsavalible(isavalible);
            }
            this.updateBatch(userList);
        }
    }

    /**
     * 修改用户左后获取作业时间
     *
     * @param userId
     * @param lastWorkTime
     */
    public void updateUserLastWorkTime(BigDecimal userId, Date lastWorkTime) {
        if (DataUtil.idIsNotNull(userId) && ObjectUtils.isNotEmpty(lastWorkTime)) {
            CusUser user = new CusUser();
            user.setId(userId);
            user.setLastWorkTime(lastWorkTime);
            this.updateById(user, null);
        }
    }

    /**
     * 通过手机号码获取用户列表
     *
     * @param mobileList 手机号码列表
     * @return List<CusUser>
     */
    public List<CusUser> queryUserByMobileList(List<String> mobileList) {
        if (ObjectUtils.isNotEmpty(mobileList)) {
            String mobileStr = mobileList.stream().collect(Collectors.joining(",", "'", "'"));
            List<String> columnList = new ArrayList<>();
            columnList.add("id");
            columnList.add("mobile");
            return this.find("mobile in (" + mobileStr + ")", null, columnList);
        }
        return Collections.emptyList();
    }
    //==================================================================================================

    /**
     * 用户默认昵称
     *
     * @param user
     */
    public void nickname(CusUser user) {
        if (StringUtils.isEmpty(user.getNickname())) {
            if (StringUtils.isNotEmpty(user.getMobile())) {
                String mobile = StringUtils.replace(user.getMobile(), user.getMobile().substring(3, 7), "****");
                user.setNickname(mobile);
            } else if (StringUtils.isNotEmpty(user.getEmail())) {
                String email = user.getEmail();
                String[] _email = email.split("@");
                String em = "****@";
                email = em + _email[1];
                System.out.println(email);
                user.setNickname(email);
            } else if (StringUtils.isNotEmpty(user.getLoginAccount())) {
                user.setNickname(user.getLoginAccount());
            }
        }
    }

    /**
     * 获取用户注册类型
     *
     * @param regForm 注册来源
     * @return 返回1注册类型，2非注册类型
     */
    private int getRegisterType(String regForm) {
        if (!UserExpandFrom.registerFrom.getKey().equals(regForm)
                && !UserExpandFrom.mobileFrom.getKey().equals(regForm)
                && !UserExpandFrom.iosFrom.getKey().equals(regForm)
                && !UserExpandFrom.androidFrom.getKey().equals(regForm)
                && !UserExpandFrom.iosThirdWeiXin.getKey().equals(regForm)
                && !UserExpandFrom.androidThirdWeiXin.getKey().equals(regForm)
                && !UserExpandFrom.iosThirdQQ.getKey().equals(regForm)
                && !UserExpandFrom.androidThirdQQ.getKey().equals(regForm)
                && !UserExpandFrom.mobileThirdWeiXin.getKey().equals(regForm)
                && !UserExpandFrom.mobileThirdQQ.getKey().equals(regForm)
                && !UserExpandFrom.pcThirdWeiXin.getKey().equals(regForm)
                && !UserExpandFrom.pcThirdQQ.getKey().equals(regForm)
                && !UserExpandFrom.appletThirdWeiXin.getKey().equals(regForm)) {
            return 2;
        }
        return 1;
    }

    /**
     * 往学员中set专业
     *
     * @param userList
     */
    private List<CusUser> setSubjectByUserList(List<CusUser> userList) {
        if (ObjectUtils.isNotEmpty(userList)) {
            userList.forEach(e -> {
                Map<String, Set<String>> subMap = new HashMap<>();
                String subjectIds = "";
                if (StringUtils.isNotEmpty(e.getSubjectIds())) {
                    subjectIds = e.getSubjectIds();
                }
                if (StringUtils.isNotEmpty(e.getNaturalSubjectIds())) {
                    subjectIds += "#" + e.getNaturalSubjectIds();
                }
                if (StringUtils.isNotEmpty(subjectIds)) {
                    String[] strArr = subjectIds.split("#");
                    Arrays.stream(strArr).forEach(str -> {
                        str = StringUtils.subHeadTailString(str, ",");
                        if (StringUtils.isNotEmpty(str)) {
                            String[] arr = str.split(",");
                            String key = arr[0];
                            Set<String> set = new HashSet<>();
                            Set<String> _set = subMap.get(key);
                            if (_set != null) {
                                set.addAll(_set);
                            }
                            if (arr.length > 1) {
                                IntStream.range(1, arr.length).forEach(index -> {
                                    set.add(arr[index]);
                                });
                            }
                            subMap.put(key, set);
                        }
                    });
                }
                if (ObjectUtils.isNotEmpty(subMap)) {
                    List<String> keyList = new ArrayList<>(subMap.keySet());
                    StringBuilder subject = new StringBuilder();
                    IntStream.range(0, keyList.size()).forEach(index -> {
                        String key = keyList.get(index);
                        subject.append(key).append(",");
                        Set<String> set = subMap.get(key);
                        if (ObjectUtils.isNotEmpty(set)) {
                            subject.append(set.stream().collect(Collectors.joining(",")));
                        }
                        if (index < keyList.size() - 1) {
                            subject.append("*");
                        }
                    });
                    e.setSubjectIds(subject.toString());
                }
            });
            String subjectIds = commonSetSubjectDataService.getSubjectIds(userList);
            if (StringUtils.isNotEmpty(subjectIds)) {
                SysSubject sysSubject = new SysSubject();
                sysSubject.setQueryIds(subjectIds);
                Map<BigDecimal, SysSubject> subjectMap = sysSubjectBiz.findSubjectToIdMap(sysSubject);
                if (ObjectUtils.isNotEmpty(subjectMap)) {
                    commonSetSubjectDataService.setSubjectData(subjectMap, userList);
                }
            }
        }
        return userList;
    }

    /***
     *  添加用户经验
     * @param users 用户列表
     * @param userGrades 经验列表
     */
    private void setUserUserExpAccountByList(List<CusUser> users, List<CusUserExpAccount> userGrades) {
        if (ObjectUtils.isNotEmpty(users)) {
            if (!ObjectUtils.isNotEmpty(userGrades)) {
                String userIds = users.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                if (StringUtils.isNotEmpty(userIds)) {
                    userGrades = cusUserExpAccountBiz.queryCusUserExpAccountListByUserIds(userIds);
                }
            }
            if (ObjectUtils.isNotEmpty(userGrades)) {
                Map<BigDecimal, CusUserExpAccount> userExpAccountMap = userGrades.stream().distinct().collect(Collectors.toMap(CusUserExpAccount::getUserId, e -> e));
                for (CusUser user : users) {
                    user.setCusUserExpAccount(userExpAccountMap.get(user.getId()));
                }
            }
        }
    }

    /**
     * 添加用户等级
     */
    private void setUserGradeConfig(List<CusUser> users, List<CusUserGradeConfig> userGradeConfigs) {
        if (ObjectUtils.isNotEmpty(users)) {
            if (!ObjectUtils.isNotEmpty(userGradeConfigs)) {
                userGradeConfigs = cusUserGradeConfigBiz.queryUserGradeConfigList();
            }
            if (ObjectUtils.isNotEmpty(users)) {
                Integer size = userGradeConfigs.size();
                for (CusUser user : users) {
                    for (int i = 0; i < size; i++) {
                        if (user.getCusUserExpAccount() != null && user.getCusUserExpAccount().getExp() != null) {
                            if (i + 1 > size) {
                                if (user.getCusUserExpAccount().getExp() >= userGradeConfigs.get(i).getExperience()) {
                                    user.setCusUserGradeConfig(userGradeConfigs.get(i));
                                }
                            } else if (user.getCusUserExpAccount().getExp() >= userGradeConfigs.get(i).getExperience() &&
                                    (i + 1 < size && user.getCusUserExpAccount().getExp() <= userGradeConfigs.get(i + 1).getExperience())) {
                                user.setCusUserGradeConfig(userGradeConfigs.get(i));
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 添加用户积分
     *
     * @param users
     */
    private void setUserIntegralAccount(List<CusUser> users) {
        if (ObjectUtils.isNotEmpty(users)) {
            String userIds = users.stream().map(e -> e.getId().toString()).distinct().collect(Collectors.joining(","));
            if (ObjectUtils.isNotEmpty(userIds)) {
                List<CusUserIntegral> cusUserIntegrals = cusUserIntegralBiz.queryUserIntegralByUserIds(userIds);
                if (ObjectUtils.isNotEmpty(cusUserIntegrals)) {
                    Map<BigDecimal, CusUserIntegral> cusUserIntegralMap = cusUserIntegrals.stream().collect(Collectors.toMap(CusUserIntegral::getUserId, e -> e));
                    for (CusUser cusUser : users) {
                        if (cusUserIntegralMap.get(cusUser.getId()) != null) {
                            cusUser.setUserIntegral(cusUserIntegralMap.get(cusUser.getId()));
                        }
                    }
                }
            }
        }
    }

    /**
     * 设置专业、等级，经验，积分，地址，会员
     *
     * @param user
     * @param subjectData
     * @return CusUser
     */
    public CusUser setUserSubjectAndGradeConfigAndEtc(CusUser user, boolean subjectData,
                                                      boolean userAddresses, boolean expRule,
                                                      boolean gradeConfig, boolean integral,
                                                      boolean userMember, boolean expAccount) {
        List<CusUser> cusUsers = new ArrayList<>();
        cusUsers.add(user);
        if (ObjectUtils.isNotEmpty(user)) {
            cusUsers = setUserSubjectAndGradeConfigAndEtc(cusUsers, subjectData, userAddresses,
                    expRule, gradeConfig, integral, userMember, expAccount);
        }
        if (ObjectUtils.isNotEmpty(cusUsers)) {
            user = cusUsers.get(0);
        }
        return user;
    }

    /**
     * 获取用户的附加专业数据
     *
     * @param userId 用户ID
     */
    public List<SysSubject> findUserSubjectData(BigDecimal userId) {
        CusUser user = this.queryUserById(userId, false, false, false, false, false, false, false);
        String subjectIds = user.getSubjectIds();
        if (StringUtils.isNotEmpty(subjectIds)) {
            return findUserSubjectList(subjectIds);
        }
        return null;
    }

    /**
     * 获取用户的专业专业（附加专业、基础专业）
     *
     * @param userId 用户ID
     * @return 专业列表（分层好的）
     */
    public List<SysSubject> findAllUserSubjectList(BigDecimal userId) {
        CusUser user = this.queryUserById(userId, false, false, false, false, false, false, false);
        if (StringUtils.isNotEmpty(user)) {
            String subjectIds = user.getSubjectIds();
            String naturalSubjectIds = user.getNaturalSubjectIds();
            String ids = "";
            if (StringUtils.isNotEmpty(subjectIds)) {
                ids = subjectIds;
            }
            if (StringUtils.isNotEmpty(naturalSubjectIds)) {
                ids += "#" + naturalSubjectIds;
            }
            if (StringUtils.isNotEmpty(ids)) {
                return findUserSubjectList(ids);
            }
        }
        return null;
    }

    /**
     * 获取用户专业列表
     *
     * @param ids 专业ID串
     * @return List<SysSubject>
     */
    private List<SysSubject> findUserSubjectList(String ids) {
        String oldIds = ids;
        ids = ids.replaceAll("＃", "").replaceAll("#", "").replaceAll(",,", ",");
        SysSubject sysSubject = new SysSubject();
        sysSubject.setQueryIds(ids);
        sysSubject.setStatus(1);
        //检查字符串中是否用有* ,拥有* 代表获取拥有所有专业
        if (StringUtils.isNotEmpty(ids) && ids.indexOf("*") != -1) {
            StringBuilder parentIds = new StringBuilder();
            //对字符串进行分组
            String[] subjectIds = oldIds.replaceAll(",,", ",").split("#");
            for (String subjectId : subjectIds) {
                if (subjectId.indexOf("*") != -1) {
                    parentIds.append(StringUtils.subHeadTailString(subjectId, ",").split(",")[0]).append(",");
                }
            }
            sysSubject.setParentIds(parentIds.toString());
            sysSubject.setAllChild(true);
        }
        return sysSubjectBiz.findLayeredSubjectList(sysSubject);
    }

    /**
     * 设置专业、等级，经验，积分，地址，会员
     *
     * @param users
     * @param subjectData
     * @return List<CusUser>
     */
    private List<CusUser> setUserSubjectAndGradeConfigAndEtc(List<CusUser> users, boolean subjectData,
                                                             boolean userAddresses, boolean expRule,
                                                             boolean gradeConfig, boolean integral,
                                                             boolean userMember, boolean expAccount) {
        if (ObjectUtils.isNotEmpty(users)) {
            if (subjectData) {
                setSubjectByUserList(users);
            }
            if (userAddresses) {
                setCusUserAddressListByUsetList(users);
            }
            if (expRule) {
            }
            if (expAccount) {
                setUserUserExpAccountByList(users, null);
            }
            if (gradeConfig) {
                setUserGradeConfig(users, null);
            }
            if (integral) {
                setUserIntegralAccount(users);
            }
            if (userMember) {
                setMemberByUserList(users);
            }
        }
        return users;
    }

    /**
     * 添加用户地址
     *
     * @param users
     */
    private void setCusUserAddressListByUsetList(List<CusUser> users) {
        if (ObjectUtils.isNotEmpty(users)) {
            String userIds = users.stream().map(e -> e.getId().toString()).distinct().collect(Collectors.joining(","));
            if (ObjectUtils.isNotEmpty(userIds)) {
                List<CusUserAddress> userAddresses = cusUserAddressBiz.queryUserAddressListByUserIds(userIds, true);
                if (ObjectUtils.isNotEmpty(userAddresses)) {
                    for (CusUser cusUser : users) {
                        List<CusUserAddress> cusUserAddresses = new ArrayList<>();
                        for (CusUserAddress cusUserAddress : userAddresses) {
                            if (cusUser.getId().equals(cusUserAddress.getUserId())) {
                                cusUserAddresses.add(cusUserAddress);
                            }
                        }
                        cusUser.setAddresses(cusUserAddresses);
                    }
                }
            }
        }
    }

    /**
     * 添加会员
     *
     * @param users
     */
    private void setMemberByUserList(List<CusUser> users) {
        if (ObjectUtils.isNotEmpty(users)) {
            String userIds = users.stream().map(e -> e.getId().toString()).distinct().collect(Collectors.joining(","));
            if (ObjectUtils.isNotEmpty(userIds)) {
                List<CusUserMemberBuyRecord> buyRecords = cusUserMemberBuyRecordBiz.queryUserBuyMemberRecordByUserIds(userIds);
                if (ObjectUtils.isNotEmpty(buyRecords)) {
                    Map<BigDecimal, CusUserMemberBuyRecord> buyRecordsMap = buyRecords.stream().collect(Collectors.toMap(CusUserMemberBuyRecord::getUserId, e -> e));
                    for (CusUser cusUser : users) {
                        if (buyRecordsMap.get(cusUser.getId()) != null) {
                            cusUser.setMemberBuyRecord(buyRecordsMap.get(cusUser.getId()));
                        }
                    }
                }
            }
        }
    }

    /**
     * 修改用户选择的专业
     *
     * @param user              用户ID
     * @param naturalSubjectIds 用户选择专业ID
     * @return CusUser
     */
    public CusUser updateUserNaturalSubjectIds(CusUser user, String naturalSubjectIds) {
        if (ObjectUtils.isNotEmpty(user)) {
            naturalSubjectIds = this.getUserNewSubjectIds(user.getNaturalSubjectIds(), naturalSubjectIds);
            user.setNaturalSubjectIds(naturalSubjectIds);
            this.updateById(user, null);
            return user;
        }
        return null;
    }

    /**
     * 修改用户附加专业
     *
     * @param userId           用户ID
     * @param courseSubjectIds 课程专业ID串列表
     * @return CusUser
     */
    public CusUser updateUserAttachSubjectIds(BigDecimal userId, List<String> courseSubjectIds) {
        if (DataUtil.idIsNotNull(userId) && ObjectUtils.isNotEmpty(courseSubjectIds)) {
            String subjectIds = courseSubjectIds.stream().collect(Collectors.joining("#"));
            return updateUserAttachSubjectIds(userId, subjectIds);
        }
        return null;
    }

    /**
     * 修改用户附加专业
     *
     * @param userId     用户ID
     * @param subjectIds 专业ID串
     * @return CusUser
     */
    public CusUser updateUserAttachSubjectIds(BigDecimal userId, String subjectIds) {
        CusUser user = this.findById(userId);
        if (ObjectUtils.isNotEmpty(user)) {
            subjectIds = this.getUserNewSubjectIds(user.getSubjectIds(), subjectIds);
            user.setSubjectIds(subjectIds);
            this.updateById(user, null);
        }
        return user;
    }

    /**
     * 获取新的专业数据ID串
     *
     * @param oldSubjectIds 原有的
     * @param newSubjectIds 新添加了
     * @return 返回处理好的专业ID串
     */
    private String getUserNewSubjectIds(String oldSubjectIds, String newSubjectIds) {
        if (StringUtils.isNotEmpty(newSubjectIds)) {
            Set<String> set = this.getSetSubjectIds(newSubjectIds);
            if (StringUtils.isNotEmpty(oldSubjectIds)) {
                Set<String> oldSet = this.getSetSubjectIds(oldSubjectIds);
                oldSet.forEach(s -> {
                    set.add(s);
                });
            }
            oldSubjectIds = set.stream().collect(Collectors.joining("#"));
        }
        return oldSubjectIds;
    }

    /**
     * 处理设置给用户的新专业ID
     *
     * @param subjectIds
     * @return Set<String>
     */
    private Set<String> getSetSubjectIds(String subjectIds) {
        String[] arr = StringUtils.subHeadTailString(subjectIds, "#").split("#");
        Set<String> set = new HashSet<>();
        Arrays.stream(arr).forEach(str -> {
            str = StringUtils.subHeadTailString(str, ",");
            String[] _arr = str.split(",");
            if (_arr.length == 1) {
                set.add("," + _arr[0] + ",");
            }
            if (_arr.length > 1) {
                for (int i = 1; i < _arr.length; i++) {
                    set.add("," + _arr[0] + "," + _arr[i] + ",");
                }
            }
        });
        return set;
    }

    /**
     * 更新学员用户信息
     *
     * @param userId   学员用户id
     * @param property 学员用户信息属性
     * @param increase 负数 减少 正数 增加
     */
    public void updateUserNumberOfStatistics(BigDecimal userId, String property, Integer increase) {
        CusUser user = this.findById(userId);
        switch (property) {
            case "studyNum"://学习次数
                user.setStudyNum(calculate(user.getStudyNum(), increase));
                break;
            case "assessNum"://评论次数
                user.setAssessNum(calculate(user.getAssessNum(), increase));
                break;
            case "qaNum"://问答次数
                user.setQaNum(calculate(user.getQaNum(), increase));
                break;
            case "examNum"://考试次数
                user.setExamNum(calculate(user.getExamNum(), increase));
                break;
            case "questionNum":
                user.setQuestionNum(calculate(user.getQuestionNum(), increase));
                break;
            case "noteNum"://课程笔记数量
                user.setNoteNum(calculate(user.getNoteNum(), increase));
                break;
            case "signNum"://学员签到次数
                user.setSignNum(calculate(user.getSignNum(), increase));
                break;
            case "joinLiveCount"://学员参加直播数
                user.setJoinLiveCount(calculate(user.getJoinLiveCount(), increase));
                break;
            case "studyTotalTime"://学员学习总时间
                user.setStudyTotalTime(calculate(user.getStudyTotalTime(), increase));
                break;
            case "isWifi":
                user.setIsWifi(increase);
        }
        this.updateById(user, null);
    }

    /**
     * 设置学员用户数据
     *
     * @param baseEntity  数据对象
     * @param setUserData 是否设置用户数据
     * @return List<E>
     */
    public void setUserData(BaseEntity baseEntity, boolean setUserData) {
        List<BaseEntity> dataList = new ArrayList<>();
        dataList.add(baseEntity);
        this.setUserData(dataList, setUserData);
    }


    /**
     * 设置学员用户数据
     *
     * @param list        数据列表
     * @param setUserData 是否设置用户数据
     * @return List<E>
     */
    public void setUserData(List<? extends BaseEntity> list, boolean setUserData) {
        try {
            if (ObjectUtils.isNotEmpty(list) && setUserData) {
                StringBuffer userIds = new StringBuffer();
                list.forEach(e -> {
                    try {
                        Method userIdM = e.getClass().getMethod("getUserId");
                        if (ObjectUtils.isNotEmpty(userIdM)) {
                            BigDecimal userId = (BigDecimal) userIdM.invoke(e);
                            if (ObjectUtils.isNotEmpty(userId)) {
                                userIds.append(userId.toString()).append(",");
                            }
                        }
                    } catch (NoSuchMethodException e1) {
                        e1.printStackTrace();
                    } catch (IllegalAccessException e1) {
                        e1.printStackTrace();
                    } catch (InvocationTargetException e1) {
                        e1.printStackTrace();
                    }
                });
                if (userIds.length() > 0) {
                    userIds.delete(userIds.length() - 1, userIds.length());
                    List<CusUser> cusUsers = this.find(" id in (" + userIds.toString() + ")", null, null);
                    if (ObjectUtils.isNotEmpty(cusUsers)) {
                        Map<BigDecimal, CusUser> cusUserMap = cusUsers.stream().collect(Collectors.toMap(es -> es.getId(), es -> es));
                        if (ObjectUtils.isNotEmpty(cusUserMap)) {
                            list.forEach(em -> {
                                Method userIdM;
                                try {
                                    userIdM = em.getClass().getMethod("getUserId");
                                    BigDecimal userId = (BigDecimal) userIdM.invoke(em);
                                    CusUser user = cusUserMap.get(userId);
                                    if (ObjectUtils.isNotEmpty(user)) {
                                        Method[] methodArr = em.getClass().getMethods();
                                        Method method = null;
                                        for (Method m : methodArr) {
                                            if (m.getName().equals("setUser")) {
                                                method = m;
                                                break;
                                            }
                                        }
                                        if (method != null) {
                                            Class<?> parameterClasses = method.getParameterTypes()[0];
                                            if (parameterClasses.equals(CusUser.class)) {//是CusUser对象的
                                                method.invoke(em, user);
                                            } else {//是Map
                                                Map<String, Object> _user = new HashMap<>();
                                                _user.put("id", user.getId());
                                                _user.put("nickname", user.getNickname());
                                                _user.put("avatar", user.getAvatar());
                                                method.invoke(em, _user);
                                            }
                                        }
                                    }
                                } catch (NoSuchMethodException e1) {
                                    e1.printStackTrace();
                                } catch (IllegalAccessException e1) {
                                    e1.printStackTrace();
                                } catch (InvocationTargetException e1) {
                                    e1.printStackTrace();
                                }
                            });
                        }
                    }
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    /**
     * 查询某一天平台用户24小时内每个小时的注册量
     *
     * @param dateTime 查询的时间
     * @return UserRegDayNum
     */
    public List<UserRegDayNum> queryUserRegDayTimeNum(String dateTime) {
        return cusUserDao.queryUserRegDayTimeNum(CusUser.class, dateTime);
    }

    /**
     * 查询用户注册地理布局
     *
     * @return 用户注册布局列表
     */
    public List<UserRegLayoutNum> queryUserRegLayoutNum() {
        return cusUserDao.queryUserRegLayoutNum(CusUser.class);
    }

    /**
     * 查询注册对比数据统计数据
     *
     * @return 统计数据对象
     */
    public UserRegFromNum queryRegFromUserNum() {
        return cusUserDao.queryRegFromUserNum(CusUser.class);
    }


    /**
     * 查询某一时间段的注册量
     *
     * @return
     */
    public List<Map<String, Object>> queryUserDayTimeNum(Map<String, Object> map) {

        if (StringUtils.isEmpty(map.get("begTime")) && StringUtils.isEmpty(map.get("endTime"))) {
            map.put("begTime", DateUtils.format(new Date(), "yyyy-MM-dd"));
            map.put("endTime", DateUtils.format(new Date(), "yyyy-MM-dd"));
        }
        return cusUserDao.queryUserDayTimeNum(CusUser.class, map);
    }

    /**
     * 创建excel导入用户
     *
     * @param cusUser
     * @return
     */
    @Transactional(rollbackFor = IllegalArgumentException.class)
    public void createExcelUser(CusUser cusUser) {
        if (cusUser == null) {
            throw new RuntimeException();
        }
        String courseIds = cusUser.getCourseIds();
        cusUser.setCourseIds(null);
        // 创建用户
        cusUser = this.createUser(cusUser);
        if (cusUser == null) {
            throw new RuntimeException();
        }
        // 赠送课程
        if (StringUtils.isNotEmpty(courseIds)) {
            courseIds = StringUtils.subHeadTailString(courseIds, ",");
            String[] arr = courseIds.split(",");
            String shopData = Arrays.stream(arr).collect(Collectors.joining("-COURSE-1,", "", "-COURSE-1"));
            Map<String, Object> createResult = orderService.createFreeOrder(cusUser.getId(), shopData);
            Boolean success = (Boolean) createResult.get("success");
            if (!success) {
                throw new RuntimeException(createResult.get("message").toString());
            }
        }
    }


    /**
     * 注册转化率
     *
     * @return
     */

    public String findRegisterConversionRate(Map map) {
        return cusUserDao.findRegisterConversionRate(CusUser.class, map);
    }

    /**
     * 购买转化率
     *
     * @return
     */

    public String findOrderConversionRate(Map map) {
        return cusUserDao.findOrderConversionRate(CusUser.class, map);
    }

    /**
     * 日活跃DUA
     *
     * @return
     */

    public String findActiveDUA(Map map) {
        return cusUserDao.findActiveDUA(CusUser.class, map);
    }


    /**
     * 7日转化
     *
     * @return
     */

    public String findSevenDayConversion() {
        return cusUserDao.findSevenDayConversion(CusUser.class);
    }

    /**
     * 30日转化
     *
     * @return
     */

    public String findThirtyDayConversion() {
        return cusUserDao.findThirtyDayConversion(CusUser.class);
    }

    /**
     * 查询某一字段的所有用户
     *
     * @param field
     * @param valueStr
     * @return
     */
    public List<CusUser> queryUserByFieldValueStr(String field, String valueStr) {
        if (StringUtils.isEmpty(field) || StringUtils.isEmpty(valueStr)) {
            return null;
        }
        StringBuilder whereSql = new StringBuilder();
        whereSql.append(field).append(" in ( ").append(valueStr).append(" )");
        return this.find(whereSql.toString(), null, null);
    }

    public String creatGifts(Map<String, Object> gifts) {
        StringBuffer massage = new StringBuffer();
        // 赠送课程
        if (StringUtils.isNotEmpty(gifts.get("courseIds"))) {
            String courseIds = StringUtils.subHeadTailString(gifts.get("courseIds").toString(), ",");
            String[] arr = courseIds.split(",");
            String shopData = Arrays.stream(arr).collect(Collectors.joining("-COURSE-1,", "", "-COURSE-1"));
            Map<String, Object> createResult = orderService.createFreeOrder(new BigDecimal(gifts.get("userId").toString()), shopData);
            Boolean success = (Boolean) createResult.get("success");
            if (!success) {
                massage.append(ResultUtil.getMessage(createResult) + "  ");
            }
        }
        if (ObjectUtils.isNotEmpty(massage)) {
            return massage.toString();
        } else {
            return "";
        }
    }


//=======================================================================================================

    /**
     * 各种数量处理
     *
     * @param number
     * @param increase
     * @return
     */
    private Integer calculate(Integer number, Integer increase) {
        number = (number == null ? 0 : number);
        number += increase;
        return number < 0 ? 0 : number;
    }

    //==============================================================

    /**
     * 查询指定时间内的注册用户量和用户总量（包含非注册的用户）
     *
     * @param type
     * @param timeSql
     * @return List<UserCountEntity>
     */
    public List<UserCountEntity> queryNewUserAndUserSumList(int type, String timeSql) {
        Map<String, Object> params = new HashMap<>();
        params.put("type", type);
        params.put("timeSql", timeSql);
        return cusUserDao.queryNewUserAndUserSumList(CusUser.class, params);
    }

    /**
     * 查询用户注册来源统计数据
     *
     * @return UserRegFromEntity
     */
    public UserRegFromEntity queryUserRegFormCountData() {
        return cusUserDao.queryUserRegFormCountData(CusUser.class);
    }

    /**
     * 查询支付及未支付用户数据
     *
     * @param date 查询时间
     */
    public Map<String, BigDecimal> queryUserPayCountData(Date date) {
        Map<String, BigDecimal> resultMap = cusUserDao.queryUserPayCountData(CusUser.class, DateUtils.format(date, "yyyy-MM-dd"));
        if (resultMap == null) {
            resultMap = new HashMap<>();
            resultMap.put("userNum", BigDecimal.ZERO);
            resultMap.put("notPayUserNum", BigDecimal.ZERO);
            resultMap.put("yesPayUserNum", BigDecimal.ZERO);
        }
        return resultMap;
    }

    /**
     * 学员学习中心历史数据统计
     * @param params
     * @return
     */
    public Map<String, Object> learningNumerical(Map params ) {
        HashMap<String, Object> res = new HashMap<>();
        //签到数
        Integer periodOfTime = cusUserSignInDao.selectPeriodOfTime(CusUserSignIn.class, params);
        res.put("signIn",periodOfTime);
        //完成试卷数量
        HashMap<String, Object> examRecord = new HashMap<>();
        examRecord.put("status",2);
        examRecord.put("startTime",params.get("startTime"));
        examRecord.put("endTime",params.get("endTime"));
        examRecord.put("isExamId",true);
        examRecord.put("userId",params.get("userId"));
//        BigDecimal examRecordCount = examRecordService.getExamRecordCount(examRecord);
//        res.put("examRecordCount",examRecordCount);
        res.put("examRecordCount",0);

        //学习时间

        HashMap<String, Object> selectParams = new HashMap<>();
        selectParams.put("beginCreateTime",params.get("startTime"));
        selectParams.put("endCreateTime",params.get("endTime"));
        selectParams.put("userId",params.get("userId"));

        List list = courseLearnFlowService.selectLearnTimeMap(selectParams);
        res.put("learnDayNum",list.size());
        return  res;
    }

    public static double divide(double a, double b, int scale) {
        BigDecimal bd1 = new BigDecimal(Double.toString(a));
        BigDecimal bd2 = new BigDecimal(Double.toString(b));
        return bd1.divide(bd2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}
